package com.zxl.study.confusion;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @auther zxl
 * @create 2023-08-12 21:04
 */
public class SaveOrderServiceImpl_V2
{
    //方法设计
    //方法的职责也应该单一
    //把方法分成两种：
    //一：功能方法：
    //      只实现某一个具体功能
    //二：组合方法
    //      用来实现业务逻辑、业务流程等，通常是 组合 功能方法 来实现具体的业务
    //      一般来说，组合方法不实现具体的业务功能，只是做组合

    /**
     * 处理客户下单的业务
     * @param orderMainModel 订单主记录的数据对象
     * @param orderDetailModelList 订单对应的多个订单明细记录的数据对象的list
     * @return 主订单的uuid
     */
    //saveSaleOrder我自己是组合方法，没任何功能实现，都是调用别人
    public Long saveSaleOrder(OrderMainModel orderMainModel, List<OrderDetailModel> orderDetailModelList)
    {
        //1：保存订单的主记录，得到主记录的uuid
        Long orderMainUuid = 0L;//OrderMainService.create()
        //2：保存订单明细记录
        this.saveOrderDetail(orderMainUuid,orderDetailModelList);

        //3：判断是否需要客户方进行采购订单的审核
        //调用：CustomerCenter4OrderApi.judgeOrderNeedAudit

        if(true){
            //4：如果需要客户审核
            this.needCustomerAudit(orderMainModel,orderDetailModelList);
        }else{
            //5：如果不需要客户审核
            //5.1：判断客户是现结客户还是月结客户
            //调用：PayAndFinanceCenter4OrderApi.getCustomerSettlementType
            boolean month = true;
            if(month){
                //5.2：如果是月结客户，就自动支付
                //调用：PayAndFinanceCenter4OrderApi.monthSettlementCustomerAutoPay
                //有两种情况，一种是支付完全成功；另外一种是额度不足，只做了部分支付
                //5.3：判断是否支付完全成功
                boolean autoPayOk = true;
                if(autoPayOk){
                    //5.4：完全支付成功，记录订单操作日志，支付完成后回修改订单状态
//                    this.payOk(orderMainModel,orderDetailModelList);

                    //6：自动进行拆单
//                    this.splitOrder(orderMainModel,orderDetailModelList);

                    //7：表示订单支付完成后的处理也完成了，发出事件：下单成功，以驱动后续的业务处理
//                    this.sendSaveOrderEvent(orderMainUuid);
                }
            }
        }



        //8：如果是现结客户，或者是月结支付额度不足，需要现金支付
        boolean cashOrSupplyMonth = true;
        if(cashOrSupplyMonth){
            //8.1：创建现金支付单
//            this.createCashPaySheet(orderMainModel,orderDetailModelList);
        }
        return 0L;
    }


    //==========================================================================================


    /**
     * 保存订单明细记录
     * @param orderMainUuid 订单主记录的uuid
     * @param orderDetailModelList 要保存的订单明细记录的list
     */
    //功能方法
    private void saveOrderDetail(Long orderMainUuid,List<OrderDetailModel> orderDetailModelList){
        //2.1：循环设置每个DetailModel，设置他们所属的orderMainUuid
        for(OrderDetailModel orderDetailModel : orderDetailModelList){
            orderDetailModel.setOrderMainUuid(orderMainUuid);
        }
        //2.2：批量保存多条明细记录
        //调用：OrderDetailService.batchCreate(list);
    }

    /**
     * 如果需要客户审核，要完成的业务功能
     * @param orderMainModel 订单主记录的model对象
     * @param orderDetailModelList 订单明细记录的list
     */
    //组合方法里面再嵌套组合方法
    private void needCustomerAudit(OrderMainModel orderMainModel,List<OrderDetailModel> orderDetailModelList){
        //4.1：设置订单状态为待客户审核
        this.setOrderState(orderMainModel.getOrderUuid(),2);

        //4.2：自动生成相应的采购审核单
        this.genOrderAuditSheet(orderMainModel,orderDetailModelList);

        //4.3：记录订单的操作日志
        this.needCustomerAuditOrderLog(orderMainModel,orderDetailModelList);

        //此时认为订单并未下单完全成功，所以不用发出事件
        //后续的业务，要等用户审核完成后，回调订单提供的方法，再进行后续的业务操作
    }

    /**
     * 设置订单状态为待客户审核
     * @param orderMainUuid
     * @param orderState
     */
    //功能方法
    private void setOrderState(Long orderMainUuid,int orderState){
        //先做数据校验，要把状态改成传入的新的状态，可能需要有一些业务前置要求
        //检查是否能够满足这个业务要求
        //比如；要把状态改成待客户审核，要求订单状态必须是 新保存的订单

        //真正来修改状态
    }

    /**
     * 生成相应的采购审核单
     * @param orderMainModel
     * @param orderDetailModelList
     */
    //功能方法
    private void genOrderAuditSheet(OrderMainModel orderMainModel,List<OrderDetailModel> orderDetailModelList){
        //数据组织
        //调用：CustomerCenter4OrderApi.genOrderAuditSheet
    }

    /**
     * 需要客户审核的时候，记录订单的操作日志
     * @param orderMainModel
     * @param orderDetailModelList
     */
    //功能方法
    private void needCustomerAuditOrderLog(OrderMainModel orderMainModel,List<OrderDetailModel> orderDetailModelList){
        //4.3：记录订单的操作日志
    }

    /**
     * 完全支付成功的业务处理
     * @param orderMainModel
     * @param orderDetailModelList
     */
    //组合方法
    private void payOk(OrderMainModel orderMainModel,List<OrderDetailModel> orderDetailModelList){
        //5.4：完全支付成功，记录订单操作日志，支付完成后返回修改订单状态
//        this.payOkOrderLog(orderMainModel,orderDetailModelList);
//        this.payOkSetOrderState(orderMainModel.getUuid(),3);

    }

    /**
     * 完全支付成功后，记录订单操作日志
     * @param orderMainModel
     * @param orderDetailModelList
     */
    //功能方法
    private void payOkOrderLog(OrderMainModel orderMainModel,List<OrderDetailModel> orderDetailModelList){
        //完全支付成功后，记录订单操作日志
    }

    /**
     * 完全支付成功后，返回修改订单状态
     * @param orderMainUuid
     * @param orderState
     */
    //功能方法
    private void payOkSetOrderState(Long orderMainUuid,int orderState){
        //先做数据校验，要把状态改成传入的新的状态，可能需要有一些业务前置要求
        //检查是否能够满足这个业务要求
        //比如；要把状态改成支付成功，要求订单状态必须是 待支付的订单

        //真正来修改状态
    }

    /**
     * 自动拆单的业务处理
     * @param orderMainModel
     * @param orderDetailModelList
     */
    //组合方法
    private  void splitOrder(OrderMainModel orderMainModel,List<OrderDetailModel> orderDetailModelList){
        Map<OrderMainModel,List<OrderDetailModel>> splitOrderMap = new HashMap<>();
        //6：自动进行拆单
        //这就要求在订单的数据结构上添加：订单 主子类型、所属的主订单的uuid
        //6.1：先按照税点进行拆单（税点可以是从前端传过来点，也可以后台重新到商品中心去获取）
        //拆分到结果，放在内存里面，先不要保存，等到最后完全拆单完成后，再一次性的批量保存
//        splitOrderMap = this.splitByTaxPoint(splitOrderMap);

        //6.2：获取客户配置的拆单规则
        //调用：CustomerCenter4OrderApi.getOrderSplitConfig

        //6.3：判断是否还需要继续拆分，如果需要
        if(true){
            //6.4：继续按照设置的规则进行拆分，（目前主要是按照会计科目进行拆单，会计科目数据从前端传过来）
//            this.splitByAccountingTitle(splitOrderMap);
//            this.splitByCustomerCategory(splitOrderMap);
        }

        //6.5：整体保存拆单的结果
//        this.saveSplitOrder(splitOrderMap);

        //6.6：记录订单操作日志，主子订单都一并记录下来
//        this.splitOrderLog(splitOrderMap);
    }

    /**
     * 按照税点进行拆单
     * @return
     */
    //功能方法
    private Map<OrderMainModel,List<OrderDetailModel>> splitByTaxPoint(Map<OrderMainModel,List<OrderDetailModel>> splitMap){

        return splitMap;
    }

    /**
     * 按照会计科目进行拆单
     * @param splitMap
     * @return
     */
    //功能方法
    private Map<OrderMainModel,List<OrderDetailModel>> splitByAccountingTitle(Map<OrderMainModel,List<OrderDetailModel>> splitMap){

        return splitMap;
    }
    /**
     * 按照客户自定义分类进行拆单
     * @param splitMap
     * @return
     */
    //功能方法
    private Map<OrderMainModel,List<OrderDetailModel>> splitByCustomerCategory(Map<OrderMainModel,List<OrderDetailModel>> splitMap){

        return splitMap;
    }

    /**
     * 整体保存拆单的结果
     * @param splitMap
     */
    //组合方法
    private void saveSplitOrder(Map<OrderMainModel,List<OrderDetailModel>> splitMap){
        //6.5.1：先批量保存主订单记录，获取返回结果，里面有对应的OrderMainUuid
//        List<OrderMainModel> list =  orderMainService.batchCreate();

        //6.5.2：循环设置相应的OrderDetailModel里面的OrderMainUuid
        //6.5.3：批量保存拆分出来的OrderDetail
//        this.saveOrderDetail(splitMap);
    }

    /**
     * 批量保存拆分出来的OrderDetail
     * @param splitMap
     */
    //功能方法
    private void saveSplitOrderDetail(Map<OrderMainModel,List<OrderDetailModel>> splitMap){
        //6.5.2：循环设置相应的OrderDetailModel里面的OrderMainUuid
        //6.5.3：批量保存拆分出来的OrderDetail

    }

    /**
     * 记录订单拆分后的操作日志，主子订单都要记录下来
     * @param splitMap
     */
    //功能方法
    private void splitOrderLog(Map<OrderMainModel,List<OrderDetailModel>> splitMap){
        //6.6：记录订单操作日志，主子订单都一并记录下来
    }

    /**
     * 发出下单成功的时间，以驱动后续的业务处理
     * @param orderMainUuid
     */
    //功能方法
    private void sendSaveOrderEvent(Long orderMainUuid){
        //7：表示订单支付完成后的处理也完成了，发出事件：下单成功，以驱动后续的业务处理
    }

    /**
     * 创建现结的支付单
     * @param orderMainModel
     * @param orderDetailModelList
     */
    //功能方法
    private void createCashPaySheet(OrderMainModel orderMainModel,List<OrderDetailModel> orderDetailModelList){
        //8.1：创建现金支付单
        //调用：PayAndFinanceCenter4OrderApi.createPaySheet
    }
}
